gboolean _ostree_gfileinfo_equal (GFileInfo *a, GFileInfo *b);
gboolean _ostree_stbuf_equal (struct stat *stbuf_a, struct stat *stbuf_b);
GFileInfo *_ostree_mode_uidgid_to_gfileinfo (mode_t mode, uid_t uid, gid_t gid);
+GVariant *_ostree_canonicalize_xattrs (GVariant *xattrs);
gboolean _ostree_validate_structureof_xattrs (GVariant *xattrs, GError **error);
static inline void
G_STATIC_ASSERT (OSTREE_REPO_MODE_BARE_SPLIT_XATTRS == 4);
static GBytes *variant_to_lenprefixed_buffer (GVariant *variant);
-static GVariant *canonicalize_xattrs (GVariant *xattrs);
#define ALIGN_VALUE(this, boundary) \
((((unsigned long)(this)) + (((unsigned long)(boundary)) - 1)) \
}
// Sort xattrs by name
-static GVariant *
-canonicalize_xattrs (GVariant *xattrs)
+GVariant *
+_ostree_canonicalize_xattrs (GVariant *xattrs)
{
// We always need to provide data, so NULL is canonicalized to the empty array
if (xattrs == NULL)
symlink_target = "";
// We always sort the xattrs now to ensure everything is in normal/canonical form.
- g_autoptr (GVariant) tmp_xattrs = canonicalize_xattrs (xattrs);
+ g_autoptr (GVariant) tmp_xattrs = _ostree_canonicalize_xattrs (xattrs);
g_autoptr (GVariant) ret
= g_variant_new ("(uuuus@a(ayay))", GUINT32_TO_BE (uid), GUINT32_TO_BE (gid),
GVariant *ret_metadata = NULL;
// We always sort the xattrs now to ensure everything is in normal/canonical form.
- g_autoptr (GVariant) tmp_xattrs = canonicalize_xattrs (xattrs);
+ g_autoptr (GVariant) tmp_xattrs = _ostree_canonicalize_xattrs (xattrs);
ret_metadata = g_variant_new (
"(uuu@a(ayay))", GUINT32_TO_BE (g_file_info_get_attribute_uint32 (dir_info, "unix::uid")),
GError **error)
{
GLNX_AUTO_PREFIX_ERROR ("Writing bareuser metadata", error);
- if (xattrs != NULL && !_ostree_validate_structureof_xattrs (xattrs, error))
- return FALSE;
- g_autoptr (GVariant) filemeta = create_file_metadata (uid, gid, mode, xattrs);
+ // Like we do elsewhere, ensure xattrs are in canonical form. We don't strictly need
+ // this because we don't actually provide this data directly as input to a checksum today,
+ // but it's good hygeine to do so.
+ g_autoptr (GVariant) tmp_xattrs = _ostree_canonicalize_xattrs (xattrs);
+ g_autoptr (GVariant) filemeta = create_file_metadata (uid, gid, mode, tmp_xattrs);
if (TEMP_FAILURE_RETRY (fsetxattr (fd, "user.ostreemeta", (char *)g_variant_get_data (filemeta),
g_variant_get_size (filemeta), 0))
g_autoptr (GVariant) metadata = g_variant_ref_sink (
g_variant_new_from_bytes (OSTREE_FILEMETA_GVARIANT_FORMAT, bytes, FALSE));
- ret_xattrs = filemeta_to_stat (&stbuf, metadata);
+ g_autoptr (GVariant) read_xattrs = filemeta_to_stat (&stbuf, metadata);
+ // Old versions of ostree may have written these xattrs in non-canonical form.
+ // In order to aid comparisons, let's canonicalize here.
+ ret_xattrs = _ostree_canonicalize_xattrs (read_xattrs);
if (S_ISLNK (stbuf.st_mode))
{
if (out_symlink)